//
//  SubscribeAction.swift
//  MagaCore
//
//  Created by MrMessy on 2023/5/18.
//

import Foundation
import ReSwift
import ReSwiftThunk
import Moya
import HandyJSON
import SwiftyStoreKit
import StoreKit
import PKHUD

enum HTEnumSubscribeAction: Action {
  case htEnumProductsInfo(var_subscribes: [HTSubscribe]?)
  case htEnumSelSub(var_selSub: HTSubscribe?)
  case htEnumCurSub(var_curSub: HTSubscribe?)
  case htEnumIntroductorySub(var_introductorySub: HTSubscribe?)
  case htEnumSetPurchasingSubscribe(var_purchasingSub: Bool?)

  // 获取订阅可用产品
  static func ht_retrieveProductsInfo() -> Thunk<HTAppState> {
    Thunk<HTAppState> { dispatch, _ in
      SwiftyStoreKit.retrieveProductsInfo(HTConfig.STATIC_subscribeProductIds) { result in
        var var_products: [Any] = []
        let var_sortOrder: [String] = HTConfig.STATIC_subscribeAscOrder
        for product in result.retrievedProducts {
          var var_params: [String: Any] = [:]
          var_params["var_productIdentifier"] = product.productIdentifier
          var_params["var_subscriptionGroupIdentifier"] = product.subscriptionGroupIdentifier
          if (product.productIdentifier == "week") {
            var_params["var_title"] = "Weekly"
            var_params["var_desc"] = "week"
            var_params["var_origin_price"] = NSDecimalNumber(string: "2.99")
            var_params["var_eachPrice"] = product.price.dividing(by: NSDecimalNumber(string: "7"))
          } else if (product.productIdentifier == "month") {
            var_params["var_title"] = "Monthly"
            var_params["var_desc"] = "month"
            var_params["var_origin_price"] = NSDecimalNumber(string: "9.99")
            var_params["var_eachPrice"] = product.price.dividing(by: NSDecimalNumber(string: "30"))
          } else if (product.productIdentifier == "year") {
            var_params["var_title"] = "Annually"
            var_params["var_desc"] = "year"
            var_params["var_origin_price"] = NSDecimalNumber(string: "109.99")
            var_params["var_eachPrice"] = product.price.dividing(by: NSDecimalNumber(string: "365"))
            var_params["var_isBestPrice"] = true
          }
          var_params["var_price"] = product.price
          var_params["var_introductoryPrice"] = product.introductoryPrice?.price
          if let var_unit = product.introductoryPrice?.subscriptionPeriod.unit.rawValue {
            if (var_unit == 0) {
              var_params["var_introductory_unit"] = "day"
            } else if (var_unit == 1) {
              var_params["var_introductory_unit"] = "week"
            } else if (var_unit == 2) {
              var_params["var_introductory_unit"] = "month"
            } else if (var_unit == 3) {
              var_params["var_introductory_unit"] = "year"
            }
          }
          var_products.append(var_params)
        }
        var var_introductorySub: HTSubscribe = HTSubscribe()
        var var_subscribes = [HTSubscribe].deserialize(from: var_products) as! [HTSubscribe]
        var_subscribes.sort(by: {(s1, s2) in
          if let identifier1 = s1.var_productIdentifier,
             let identifier2 = s2.var_productIdentifier,
             let index1 = var_sortOrder.firstIndex(of: identifier1),
             let index2 = var_sortOrder.firstIndex(of: identifier2) {
            return index1 < index2
          }
          return false
        })
        var_subscribes.sort(by: {(s1, s2) in
          return s1.var_introductoryPrice != nil
        })

        for subscribe in var_subscribes {
          if (subscribe.var_introductoryPrice != nil) {
            var_introductorySub = subscribe
            break
          }
        }

        dispatch(HTEnumSubscribeAction.htEnumIntroductorySub(var_introductorySub: var_introductorySub))
        dispatch(HTEnumSubscribeAction.htEnumProductsInfo(var_subscribes: var_subscribes))
          if let sub = var_subscribes.first {
              dispatch(ht_selSub(sub: sub))
          }
        
      }
    }
  }

  // 选择订阅产品
  static func ht_selSub(sub: HTSubscribe) -> Thunk<HTAppState> {
    Thunk<HTAppState> { dispatch, _ in
      dispatch(HTEnumSubscribeAction.htEnumSelSub(var_selSub: sub))
    }
  }

  // 获取当前订阅的信息
  static func ht_getCurrentSubscriptionInfo(callback: ((HTSubscribe?) -> Void)?) -> Thunk<HTAppState> {
    Thunk<HTAppState> { dispatch, _ in
      let appleValidator = AppleReceiptValidator(service: HTConfig.STATIC_subscribeService, sharedSecret: HTConfig.STATIC_subscribeSecret)
      SwiftyStoreKit.verifyReceipt(using: appleValidator) { result in
        switch result {
        case .success(let receipt):
          let purchaseResult = SwiftyStoreKit.verifySubscriptions(
            ofType: .autoRenewable, // or .nonRenewing (see below)
            productIds: HTConfig.STATIC_subscribeProductIds,
            inReceipt: receipt)

          switch purchaseResult {
          case .purchased(let expiryDate, let items):
            var var_params: [String: Any] = [:]
            let var_sortOrder: [String] = HTConfig.STATIC_subscribeDescOrder
            let var_filteredItems = items.filter {$0.subscriptionExpirationDate! > Date()}
            let var_sortedItems: [ReceiptItem] = var_filteredItems.sorted(by: {(s1, s2) in
              let identifier1 = s1.productId
              let identifier2 = s2.productId
              let index1 = var_sortOrder.firstIndex(of: identifier1)
              let index2 = var_sortOrder.firstIndex(of: identifier2)
              return index1! < index2!
            })

            if let var_curSub = var_sortedItems.first {
              if (var_curSub.productId == "week") {
                var_params["var_title"] = "Weekly"
              } else if (var_curSub.productId == "month") {
                var_params["var_title"] = "Monthly"
              } else if (var_curSub.productId == "year") {
                var_params["var_title"] = "Annually"
              }
              var_params["var_expiredDate"] = expiryDate.formatString(dateFormat: "MMM dd,YYYY")
              let var_curSubscribe = HTSubscribe.deserialize(from: var_params)
              dispatch(HTEnumSubscribeAction.htEnumCurSub(var_curSub: var_curSubscribe))

              UserDefaults().set(expiryDate.formatString(dateFormat: "MMM dd,YYYY"), forKey: HTConfig.STATIC_userDefaults_userExpiredDate)
              HTNetworkManager().ht_requestForBuried(.htEnumSubscribeStatus(var_status: "1"))
              dispatch(HTEnumShareAction.ht_shareConfig(var_p1: var_curSub.productId, var_p2: "2"))

//              if let receiptURL = Bundle.main.appStoreReceiptURL {
//                do {
//                        let receiptData = try Data(contentsOf: receiptURL)
//                        let receiptString = receiptData.base64EncodedString(options: .endLineWithLineFeed)
                  let receiptString : String = receipt["latest_receipt"] as? String ?? ""
                  HTNetworkManager().ht_request(.htEnumSubscribeRestore(var_pid: var_curSub.productId, var_receipt: receiptString)) { (result) in
                    if (result.var_status == "200") {
                      let var_dataDist = result.ht_dataDist()
                      let var_local: [String: Any] = var_dataDist?["local"] as! [String : Any]
                      let var_auto_renew_status: Int
                      if var_local["auto_renew_status"] is Int {
                        var_auto_renew_status = var_local["auto_renew_status"] as! Int
                      } else {
                        var_auto_renew_status = Int(var_local["auto_renew_status"] as! String)!
                      }
                      var var_curSubscribe_new = var_curSubscribe
                      var_curSubscribe_new?.var_auto_renew_status = var_auto_renew_status
                      dispatch(HTEnumSubscribeAction.htEnumCurSub(var_curSub: var_curSubscribe_new))
                    }
                  }
//                    } catch {
//                        print("无法读取 App Store 凭证文件: \(error.localizedDescription)")
//                    }
//              }

              if (callback != nil) {
                callback!(var_curSubscribe!)
              }
            } else {
              print("没有当前订阅")
              UserDefaults().set(nil, forKey: HTConfig.STATIC_userDefaults_userExpiredDate)
              HTNetworkManager().ht_requestForBuried(.htEnumSubscribeStatus(var_status: "2"))
              if (callback != nil) {
                callback!(nil)
              }
            }
          case .expired(_, _):
            UserDefaults().set(nil, forKey: HTConfig.STATIC_userDefaults_userExpiredDate)
            HTNetworkManager().ht_requestForBuried(.htEnumSubscribeStatus(var_status: "2"))
            if (callback != nil) {
              callback!(nil)
            }
          case .notPurchased:
            UserDefaults().set(nil, forKey: HTConfig.STATIC_userDefaults_userExpiredDate)
            HTNetworkManager().ht_requestForBuried(.htEnumSubscribeStatus(var_status: "2"))
            if (callback != nil) {
              callback!(nil)
            }
          }

        case .error(let error):
          print("Receipt verification failed: \(error)")
          UserDefaults().set(nil, forKey: HTConfig.STATIC_userDefaults_userExpiredDate)
          HTNetworkManager().ht_requestForBuried(.htEnumSubscribeStatus(var_status: "2"))
          if (callback != nil) {
            callback!(nil)
          }
        }
      }
    }
  }

  // 订阅支付
  static func ht_purchaseProduct(productId: String, andSuccess: (() -> Void)?, andFail: (() -> Void)?) -> Thunk<HTAppState> {
    Thunk<HTAppState> { dispatch, _ in
      HUD.show(.progress)
      dispatch(ht_setPurchasingSubscribe(var_purchasingSub: true))
      SwiftyStoreKit.purchaseProduct(productId) { result in
        switch result {
        case .success(let purchase):
          print("Purchase Success: \(purchase.productId)")
          HUD.hide()

          if let receiptURL = Bundle.main.appStoreReceiptURL {
            do {
                    let receiptData = try Data(contentsOf: receiptURL)
                    let receiptString = receiptData.base64EncodedString(options: .endLineWithLineFeed)

              HTNetworkManager().ht_request(.htEnumSubscribeBind(var_pid: purchase.productId, var_receipt: receiptString)) { (result) in
                if (result.var_status == "200") {
                  dispatch(ht_getCurrentSubscriptionInfo(callback: nil))
                }
              }
                } catch {
                    print("无法读取 App Store 凭证文件: \(error.localizedDescription)")
                }
          }


          DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            dispatch(ht_setPurchasingSubscribe(var_purchasingSub: false))
          }
          if (andSuccess != nil) {
            andSuccess!()
          }
        case .error(let error):
          switch error.code {
          case .unknown: print("Unknown error. Please contact support")
          case .clientInvalid: print("Not allowed to make the payment")
          case .paymentCancelled: break
          case .paymentInvalid: print("The purchase identifier was invalid")
          case .paymentNotAllowed: print("The device is not allowed to make the payment")
          case .storeProductNotAvailable: print("The product is not available in the current storefront")
          case .cloudServicePermissionDenied: print("Access to cloud service information is not allowed")
          case .cloudServiceNetworkConnectionFailed: print("Could not connect to the network")
          case .cloudServiceRevoked: print("User has revoked permission to use this cloud service")
          default: print((error as NSError).localizedDescription)
          }
          HUD.hide()
          DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            dispatch(ht_setPurchasingSubscribe(var_purchasingSub: false))
          }
          if (andFail != nil) {
            andFail!()
          }
        }
      }
    }
  }

  // 恢复购买
  static func ht_restorePurchases() -> Thunk<HTAppState> {
    Thunk<HTAppState> { dispatch, _ in
      HUD.show(.progress)
      SwiftyStoreKit.restorePurchases { results in
        HUD.hide()
        if results.restoreFailedPurchases.isEmpty {
          HUD.flash(.labeledSuccess(title: "", subtitle: "Subscription status updated"), delay: 1.0)
          // 恢复购买成功
          print("Restore Success")
          // 在此处执行相关操作，例如解锁功能或更新用户订阅状态等
          dispatch(ht_getCurrentSubscriptionInfo(callback: nil))
        } else {
          HUD.flash(.labeledError(title: "", subtitle: "Subscription status update failed"), delay: 1.0)
          // 恢复购买失败
          print("Restore Failed: \(results.restoreFailedPurchases)")
        }
      }
    }
  }

  static func ht_setPurchasingSubscribe(var_purchasingSub: Bool?)-> Thunk<HTAppState> {
    Thunk<HTAppState> { dispatch, _ in
      dispatch(HTEnumSubscribeAction.htEnumSetPurchasingSubscribe(var_purchasingSub: var_purchasingSub))
    }
  }
}
